﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Comissoes.Utilities;

namespace Comissoes.Models
{
    public class ComissoesModel
    {
        public COMISSOES comissao { get; set; }
        public SelectList Tipos { get; private set; }
        public SelectList COD_CDPG { get; private set; }
        public List<string> erros { get; private set; }
        xcontEntities db = new xcontEntities();

        public Boolean SemErros()
        {
            return !this.erros.Any();
        }

        private void NewComissoesModel()
        {
            Int32? NUMERO_COMS = 1;

            if (db.COMISSOES.Any())
            {
                NUMERO_COMS += Convertions.Inteiro(db.COMISSOES.OrderByDescending(t => t.NUMERO_COMS).First().NUMERO_COMS);
            }

            this.comissao = new COMISSOES
            {
                NUMERO_COMS = NUMERO_COMS.ToString(),
                CONDICOES_PAGAMENTO = new CONDICOES_PAGAMENTO()
            };
            this.CreateSelectList();
        }

        public ComissoesModel(Int32? ID_COMS)
        {
            this.erros = new List<string>();
            if (ID_COMS == 0)
            {
                NewComissoesModel();
            }
            else
            {

                this.comissao = db.COMISSOES.FirstOrDefault(t => t.ID_COMS == ID_COMS);
                this.comissao.CONDICOES_PAGAMENTOReference.Load();
                this.comissao.VENDEDORESReference.Load();
                this.comissao.VENDEDORES.PESSOASReference.Load();
                this.comissao.CLIENTESReference.Load();
                this.comissao.CLIENTES.PESSOASReference.Load();

                this.CreateSelectList();
            }
        }

        private void CreateSelectList()
        {
            List<SelectListItem> tipos = new List<SelectListItem>
            {
                new SelectListItem { Value = "A", Text = "Crédito" },
                new SelectListItem { Value = "B", Text = "Débito" }
            };

            this.Tipos = new SelectList(tipos, "value", "text", this.comissao.TIPO_COMS);
            this.COD_CDPG = new SelectList(db.CONDICOES_PAGAMENTO, "COD_CDPG", "DESC_CDPG", this.comissao.CONDICOES_PAGAMENTO.COD_CDPG);
        }

        public void UpdateValidate(HttpRequestBase request)
        {
            if (String.IsNullOrEmpty(request["NUMERO_COMS"]))this.erros.Add("É necessário informar o número do título.");
            if (String.IsNullOrEmpty(request["DATAVENC_COMS"]))this.erros.Add("É necessário informar a data de vencimento do título.");
            if (String.IsNullOrEmpty(request["VALOR_COMS"]))this.erros.Add("É necessário informar o valor do título.");
            if (String.IsNullOrEmpty(request["COD_CLI"]))this.erros.Add("É necessário informar o cliente.");
            if (String.IsNullOrEmpty(request["COD_VEND"]))this.erros.Add("É necessário informar o vendedor.");
            if (String.IsNullOrEmpty(request["COD_CDPG"]))this.erros.Add("É necessário informar a condição de pagamento.");                
            if (String.IsNullOrEmpty(request["DATAFAT_COMS"]) && !String.IsNullOrEmpty(request["VALPAG_COMS"]))this.erros.Add("É necessário informar o valor pago quando a data de faturamento for informada.");
            if (!String.IsNullOrEmpty(request["DATAFAT_COMS"]) && String.IsNullOrEmpty(request["VALPAG_COMS"]))this.erros.Add("É necessário informar a data de faturamento quando o valor pago for informado.");
        }

        public void Update(HttpRequestBase request)
        {
            try
            {
                Int32? COD_VEND = Convertions.Inteiro(request["COD_VEND"]);
                Int32? COD_CLI = Convertions.Inteiro(request["COD_CLI"]);
                Int32? COD_CDPG = Convertions.Inteiro(request["COD_CDPG"]);

                CONDICOES_PAGAMENTO condicao = db.CONDICOES_PAGAMENTO
                                                 .Include("DIAS_CONDICAO_PAGAMENTO")
                                                 .FirstOrDefault(t => t.COD_CDPG == COD_CDPG);

                if (this.comissao.ID_COMS != 0)
                {
                    this.comissao.VALOR_COMS = Convertions.Decimal(request["VALOR_COMS"]);
                    this.comissao.VENDEDORES = db.VENDEDORES.FirstOrDefault(t => t.COD_VEND == COD_VEND);
                    this.comissao.CLIENTES = db.CLIENTES.FirstOrDefault(t => t.COD_CLI == COD_CLI);
                    this.comissao.DATAVENC_COMS = Convertions.Data(request["DATAVENC_COMS"]);
                    this.comissao.DATAFAT_COMS = Convertions.Data(request["DATAFAT_COMS"]).Value.AddDays(condicao.DIA_CDPG ?? 0);
                    this.comissao.VALPAG_COMS = Convertions.Decimal(request["VALPAG_COMS"]);
                    this.comissao.NUMERO_COMS = request["NUMERO_COMS"];
                    this.comissao.STATUS_COMS = Convertions.Decimal(request["VALPAG_COMS"]).HasValue ? "B" : "A";
                }
                else
                {
                    Int32 letra = 65;
                    if (condicao.DIAS_CONDICAO_PAGAMENTO.Any())
                    {
                        Decimal Valor = Convertions.Decimal(request["VALOR_COMS"]) ?? 0;
                        DateTime DATAVENC_COMS, Data = Convertions.Data(request["DATAVENC_COMS"]) ?? DateTime.Now;

                        IQueryable<DIAS_CONDICAO_PAGAMENTO> d = db.DIAS_CONDICAO_PAGAMENTO.Where(t => t.CONDICOES_PAGAMENTO.COD_CDPG == COD_CDPG).OrderBy(t => t.DIA_DICP);
                        Int32 dias = d.Count(), dia = 0, PARCELA = 1;

                        List<decimal> parcelas = new List<decimal>();

                        Decimal resto = Valor - ((Int32)(Valor / dias) * dias);

                        foreach (var i in d)
                        {
                            Decimal parcela = Math.Round((Int32)Valor / dias + resto, 2);
                            DATAVENC_COMS = Data.AddDays((Double)i.DIA_DICP + dia);

                            if (PeriodosOptions.LastDayOfMonthFromInteger(Data) == 31)
                            {
                                dia++;
                            }

                            if (PeriodosOptions.LastDayOfMonthFromInteger(Data) == 28)
                            {
                                dia -= 2;
                            }

                            db.AddToCOMISSOES(new COMISSOES
                            {
                                CONDICOES_PAGAMENTO = condicao,
                                VALOR_COMS = parcela,
                                VENDEDORES = db.VENDEDORES.FirstOrDefault(t => t.COD_VEND == COD_VEND),
                                CLIENTES = db.CLIENTES.FirstOrDefault(t => t.COD_CLI == COD_CLI),
                                DATAVENC_COMS = DATAVENC_COMS,
                                DATAFAT_COMS = String.IsNullOrEmpty(request["DATAFAT_COMS"]) ? null : (DateTime?)Data,
                                VALPAG_COMS = String.IsNullOrEmpty(request["VALPAG_COMS"]) ? null : (Decimal?)parcela,
                                NUMERO_COMS = request["NUMERO_COMS"],
                                LETRA_COMS = string.Format("{0}", (Char)letra),
                                TIPO_COMS = request["TIPO_COMS"],
                                STATUS_COMS = Convertions.Decimal(request["VALPAG_COMS"]).HasValue ? "B" : "A",
                                PARCELA_COMS = PARCELA
                            });

                            resto = 0;
                            letra++;
                            PARCELA++;
                        }
                    }
                    else if (condicao.PARCELAS_CDPG.HasValue)
                    {
                        db.AddToCOMISSOES(new COMISSOES
                        {
                            CONDICOES_PAGAMENTO = condicao,
                            VALOR_COMS = Convertions.Decimal(request["VALOR_COMS"]),
                            VENDEDORES = db.VENDEDORES.FirstOrDefault(t => t.COD_VEND == COD_VEND),
                            CLIENTES = db.CLIENTES.FirstOrDefault(t => t.COD_CLI == COD_CLI),
                            DATAVENC_COMS = Convertions.Data(request["DATAVENC_COMS"]),
                            DATAFAT_COMS = Convertions.Data(request["DATAFAT_COMS"]).Value.AddDays(condicao.DIA_CDPG ?? 0),
                            VALPAG_COMS = Convertions.Decimal(request["VALPAG_COMS"]),
                            NUMERO_COMS = request["NUMERO_COMS"],
                            LETRA_COMS = string.Format("{0}", (Char)letra),
                            TIPO_COMS = request["TIPO_COMS"],
                            STATUS_COMS = Convertions.Decimal(request["VALPAG_COMS"]).HasValue ? "B" : "A",
                            PARCELA_COMS = 1
                        });
                    }
                    else
                    {
                        db.AddToCOMISSOES(new COMISSOES
                        {
                            VALOR_COMS = Convertions.Decimal(request["VALOR_COMS"]),
                            VENDEDORES = db.VENDEDORES.FirstOrDefault(t => t.COD_VEND == COD_VEND),
                            CLIENTES = db.CLIENTES.FirstOrDefault(t => t.COD_CLI == COD_CLI),
                            DATAVENC_COMS = Convertions.Data(request["DATAVENC_COMS"]),
                            DATAFAT_COMS = Convertions.Data(request["DATAFAT_COMS"]),
                            VALPAG_COMS = Convertions.Decimal(request["VALPAG_COMS"]),
                            NUMERO_COMS = request["NUMERO_COMS"],
                            LETRA_COMS = string.Format("{0}", (Char)letra),
                            TIPO_COMS = request["TIPO_COMS"],
                            STATUS_COMS = Convertions.Decimal(request["VALPAG_COMS"]).HasValue ? "B" : "A",
                            PARCELA_COMS = 1
                        });
                    }
                }

                db.SaveChanges();
            }
            catch (Exception ex)
            {
               this.erros.Add(ex.Message);
                if (ex.InnerException != null)
                   this.erros.Add(ex.InnerException.Message);
            }
        }

        public void Confirmar(String Comissoes)
        {
            try
            {
                if (this.comissao.ID_COMS != 0)
                {
                    comissao.STATUS_COMS = "C";
                }
                else
                {
                    String[] c = Comissoes.Split(',');

                    foreach (String i in c)
                    {
                        Int32? ID_COMS = Convertions.Inteiro(i);
                        if (ID_COMS.HasValue)
                        {
                            COMISSOES comissao = db.COMISSOES.First(t => t.ID_COMS == ID_COMS);
                            comissao.STATUS_COMS = "C";
                        }
                    }
                }

                db.SaveChanges();
            }
            catch (Exception ex)
            {
               this.erros.Add(ex.Message);
            }
        }
    }
}